package com.example.tpl.system.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.tpl.system.dao.MenuDao;
import com.example.tpl.system.dao.RoleDao;
import com.example.tpl.system.dao.RoleDeptDao;
import com.example.tpl.system.dao.RoleMenuDao;
import com.example.tpl.system.dao.UserDao;
import com.example.tpl.system.dao.UserRoleDao;
import com.example.tpl.system.entity.MenuBean;
import com.example.tpl.system.entity.RoleBean;
import com.example.tpl.system.entity.RoleDeptBean;
import com.example.tpl.system.entity.RoleMenuBean;
import com.example.tpl.system.entity.UserBean;
import com.example.tpl.system.entity.UserRoleBean;
import com.example.tpl.system.service.RoleService;
import com.example.tpl.system.util.Result;
import com.example.tpl.system.util.ResultPage;
import com.example.tpl.system.vo.common.DeleteBatchReqVo;
import com.example.tpl.system.vo.common.QueryDetailReqVo;
import com.example.tpl.system.vo.common.UpdateStatusReq;
import com.example.tpl.system.vo.req.AllocatedListReq;
import com.example.tpl.system.vo.req.CancelAuthUserAllReq;
import com.example.tpl.system.vo.req.CancelAuthUserReq;
import com.example.tpl.system.vo.req.QueryRoleMenuReq;
import com.example.tpl.system.vo.req.QueryRoleReqVo;
import com.example.tpl.system.vo.req.RoleMenuReq;
import com.example.tpl.system.vo.req.RoleReqVo;
import com.example.tpl.system.vo.req.SelectAuthUserAllReq;
import com.example.tpl.system.vo.req.UnallocatedListReq;
import com.example.tpl.system.vo.resp.RoleMenuData;
import com.example.tpl.system.vo.resp.RoleMenuResp;
import com.example.tpl.system.vo.resp.RoleRespVo;
import com.example.tpl.system.vo.resp.UserRespVo;

/**
 * 描述：角色信息
 * 作者：刘飞华
 * 日期：2025-01-14 10:40:16
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private RoleMenuDao roleMenuDao;

    @Autowired
    private RoleDeptDao roleDeptDao;

    @Autowired
    private MenuDao menuDao;

    @Autowired
    private UserDao userDao;

    /**
     * 添加角色信息
     *
     * @param role 请求参数
     * @return int
     * @author 刘飞华
     * @date: 2025-01-14 10:40:16
     */
    @Override
    public Result<Integer> addRole(RoleReqVo role) {
        String roleName = role.getRoleName();
        String roleKey = role.getRoleKey();

        if (roleDao.selectCount(Wrappers.<RoleBean>lambdaQuery().eq(RoleBean::getRoleName, roleName)) > 0) {
            return Result.error("角色名称已存在");
        }

        if (roleDao.selectCount(Wrappers.<RoleBean>lambdaQuery().eq(RoleBean::getRoleKey, roleKey)) > 0) {
            return Result.error("角色权限已存在");
        }

        RoleBean bean = new RoleBean();
        bean.setRoleName(roleName); //名称
        bean.setRoleKey(roleKey); //角色权限字符串
        bean.setDataScope(role.getDataScope()); //数据范围（1：全部数据权限 2：自定数据权限 3：本部门数据权限 4：本部门及以下数据权限）
        bean.setStatus(role.getStatus()); //状态(1:正常，0:禁用)
        bean.setRemark(role.getRemark()); //备注
        bean.setDelFlag(1); //删除标志（0代表删除 1代表存在）

        int i = roleDao.insert(bean);
        return Result.success(i);
    }

    /**
     * 删除角色信息
     *
     * @param role 请求参数
     * @return int
     * @author 刘飞华
     * @date: 2025-01-14 10:40:16
     */
    @Override
    public Result<Integer> deleteRole(DeleteBatchReqVo role) {
        List<Long> ids = role.getIds();
        if (ids.contains(1L)) {
            return Result.error("不允许操作超级管理员角色");
        }

        for (Long id : ids) {
            RoleBean roleBean = roleDao.selectById(id);
            if (roleBean == null) {
                return Result.error("角色不存在");
            }

            if (userRoleDao.selectCount(Wrappers.<UserRoleBean>lambdaQuery().eq(UserRoleBean::getRoleId, id)) > 0) {
                return Result.error("已分配,不能删除");
            }
        }

        roleMenuDao.delete(Wrappers.<RoleMenuBean>lambdaQuery().in(RoleMenuBean::getRoleId, ids));

        roleDeptDao.delete(Wrappers.<RoleDeptBean>lambdaQuery().in(RoleDeptBean::getRoleId, ids));

        int i = roleDao.deleteByIds(ids);

        return Result.success(i);
    }

    /**
     * 更新角色信息
     *
     * @param role 请求参数
     * @return int
     * @author 刘飞华
     * @date: 2025-01-14 10:40:16
     */
    @Override
    public Result<Integer> updateRole(RoleReqVo role) {
        Long id = role.getId();
        String roleName = role.getRoleName();
        String roleKey = role.getRoleKey();

        if (id == 1) {
            return Result.error("不允许操作超级管理员角色");
        }

        if (roleDao.selectCount(Wrappers.<RoleBean>lambdaQuery().eq(RoleBean::getId, id)) == 0) {
            return Result.error("角色信息不存在");
        }

        if (roleDao.selectCount(Wrappers.<RoleBean>lambdaQuery()
                                        .eq(RoleBean::getRoleName, roleName)
                                        .ne(RoleBean::getId, id)) > 0) {
            return Result.error("角色名称已存在");
        }

        if (roleDao.selectCount(Wrappers.<RoleBean>lambdaQuery()
                                        .eq(RoleBean::getRoleKey, roleKey)
                                        .ne(RoleBean::getId, id)) > 0) {
            return Result.error("角色权限已存在");
        }

        RoleBean bean = new RoleBean();
        bean.setId(id);//主键
        bean.setRoleName(role.getRoleName());//名称
        bean.setRoleKey(role.getRoleKey());//角色权限字符串
        bean.setDataScope(role.getDataScope());//数据范围（1：全部数据权限 2：自定数据权限 3：本部门数据权限 4：本部门及以下数据权限）
        bean.setStatus(role.getStatus());//状态(1:正常，0:禁用)
        bean.setRemark(role.getRemark());//备注

        int i = roleDao.updateById(bean);
        return Result.success(i);
    }

    /**
     * 更新角色信息状态
     *
     * @param role 请求参数
     * @return int
     * @author 刘飞华
     * @date: 2025-01-14 10:40:16
     */
    @Override
    public Result<Integer> updateRoleStatus(UpdateStatusReq role) {
        if (role.getIds().contains(1L)) {
            return Result.error("不允许操作超级管理员角色");
        }

        int i = roleDao.update(Wrappers.<RoleBean>lambdaUpdate()
                                       .set(RoleBean::getStatus, role.getStatus())
                                       .in(RoleBean::getId, role.getIds()));
        return Result.success(i);
    }

    /**
     * 查询角色信息详情
     *
     * @param role 请求参数
     * @return RoleResp
     * @author 刘飞华
     * @date: 2025-01-14 10:40:16
     */
    @Override
    public Result<RoleRespVo> queryRoleDetail(QueryDetailReqVo role) {

        RoleBean roleBean = roleDao.selectById(role.getId());
        if (roleBean == null) {
            return Result.error("角色信息不存在");
        }

        RoleRespVo resp = new RoleRespVo();
        resp.setId(roleBean.getId());//主键
        resp.setRoleName(roleBean.getRoleName());//名称
        resp.setRoleKey(roleBean.getRoleKey());//角色权限字符串
        resp.setDataScope(roleBean.getDataScope());//数据范围（1：全部数据权限 2：自定数据权限 3：本部门数据权限 4：本部门及以下数据权限）
        resp.setStatus(roleBean.getStatus());//状态(1:正常，0:禁用)
        resp.setRemark(roleBean.getRemark());//备注
        resp.setDelFlag(roleBean.getDelFlag());//删除标志（0代表删除 1代表存在）
        resp.setCreateTime(roleBean.getCreateTime());//创建时间
        resp.setUpdateTime(roleBean.getUpdateTime());//修改时间

        return Result.success(resp);
    }

    /**
     * 查询角色信息列表
     *
     * @param role 请求参数
     * @return RoleResp
     * @author 刘飞华
     * @date: 2025-01-14 10:40:16
     */
    @Override
    public Result<ResultPage<RoleRespVo>> queryRoleList(QueryRoleReqVo role) {
        LambdaQueryWrapper<RoleBean> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(role.getRoleName() != null, RoleBean::getRoleName, role.getRoleName());
        queryWrapper.like(role.getRoleKey() != null, RoleBean::getRoleKey, role.getRoleKey());
        queryWrapper.eq(role.getStatus() != null, RoleBean::getStatus, role.getStatus());

        Page<RoleBean> page = roleDao.selectPage(new Page<>(role.getPageNo(), role.getPageSize()), queryWrapper);

        List<RoleRespVo> list = page.getRecords().stream().map(x -> {
            RoleRespVo resp = new RoleRespVo();
            resp.setId(x.getId());//主键
            resp.setRoleName(x.getRoleName());//名称
            resp.setRoleKey(x.getRoleKey());//角色权限字符串
            resp.setDataScope(x.getDataScope());//数据范围（1：全部数据权限 2：自定数据权限 3：本部门数据权限 4：本部门及以下数据权限）
            resp.setStatus(x.getStatus());//状态(1:正常，0:禁用)
            resp.setRemark(x.getRemark());//备注
            resp.setDelFlag(x.getDelFlag());//删除标志（0代表删除 1代表存在）
            resp.setCreateTime(x.getCreateTime());//创建时间
            resp.setUpdateTime(x.getUpdateTime());//修改时间
            return resp;
        }).collect(Collectors.toList());

        return Result.success(new ResultPage<>(list, page.getCurrent(), page.getSize(), page.getTotal()));

    }

    /**
     * 查询角色关联的菜单
     *
     * @param roleMenuReq 请求参数
     * @return MenuRespVo
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<RoleMenuResp> queryRoleMenu(QueryRoleMenuReq roleMenuReq) {
        Long roleId = roleMenuReq.getRoleId();//角色id

        List<Long> menuIds = new ArrayList<>();
        List<RoleMenuData> menuList = new ArrayList<>();

        List<MenuBean> list = menuDao.selectList(null);

        for (MenuBean menu : list) {
            Long id = menu.getId();
            menuIds.add(id);
            RoleMenuData menuData = new RoleMenuData();
            menuData.setId(id);
            menuData.setKey(id + "");
            menuData.setParentId(menu.getParentId());
            menuData.setTitle(menu.getMenuName());
            menuData.setLabel(menu.getMenuName());
            menuData.setPenultimate(menu.getParentId() == 2);
            menuData.setLeaf(menu.getParentId() == 3);

            menuList.add(menuData);
        }

        if (!roleId.equals(1L)) {
            menuIds.clear();
            menuIds = roleMenuDao.queryMenuByRoleId(roleId);
        }

        return Result.success(new RoleMenuResp(menuIds, menuList));
    }

    /**
     * 更新角色关联的菜单
     *
     * @param roleMenuReq 请求参数
     * @return Integer
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<Integer> updateRoleMenu(RoleMenuReq roleMenuReq) {
        List<Long> menuIds = roleMenuReq.getMenuIds();
        Long roleId = roleMenuReq.getRoleId();

        if (roleId.equals(1L)) {
            return Result.error("不允许操作超级管理员角色");
        }

        roleMenuDao.delete(Wrappers.<RoleMenuBean>lambdaUpdate().eq(RoleMenuBean::getRoleId, roleId));
        menuIds.forEach(menuId -> roleMenuDao.insert(new RoleMenuBean(roleId, menuId)));

        return Result.success();
    }

    /**
     * 查询已分配用户角色列表
     *
     * @param req 请求参数
     * @return UserRespVo
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<ResultPage<UserRespVo>> queryAllocatedList(AllocatedListReq req) {
        IPage<UserBean> page = userDao.queryAllocatedList(new Page<>(req.getPageNo(), req.getPageSize()), req.getRoleId(), req.getMobile(), req.getUserName());


        List<UserRespVo> list = page.getRecords()
                .stream()
                .map(x -> {
                    UserRespVo resp = new UserRespVo();
                    resp.setId(x.getId());//主键
                    resp.setMobile(x.getMobile());//手机号码
                    resp.setUserName(x.getUserName());//用户账号
                    resp.setNickName(x.getNickName());//用户昵称
                    resp.setUserType(x.getUserType());//用户类型（00系统用户）
                    resp.setAvatar(x.getAvatar());//头像路径
                    resp.setEmail(x.getEmail());//用户邮箱
                    resp.setPassword(x.getPassword());//密码
                    resp.setStatus(x.getStatus());//状态(1:正常，0:禁用)
                    resp.setDeptId(x.getDeptId());//部门ID
                    resp.setLoginIp(x.getLoginIp());//最后登录IP
                    resp.setLoginDate(x.getLoginDate());//最后登录时间
                    resp.setLoginBrowser(x.getLoginBrowser());//浏览器类型
                    resp.setLoginOs(x.getLoginOs());//操作系统
                    resp.setPwdUpdateDate(x.getPwdUpdateDate());//密码最后更新时间
                    resp.setRemark(x.getRemark());//备注
                    resp.setDelFlag(x.getDelFlag());//删除标志（0代表删除 1代表存在）
                    resp.setCreateTime(x.getCreateTime());//创建时间
                    resp.setUpdateTime(x.getUpdateTime());//修改时间
                    return resp;
                })
                .collect(Collectors.toList());

        return Result.success(new ResultPage<>(list, page.getCurrent(), page.getSize(), page.getTotal()));
    }

    /**
     * 查询未分配用户角色列表
     *
     * @param req 请求参数
     * @return UserRespVo
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<ResultPage<UserRespVo>> queryUnallocatedList(UnallocatedListReq req) {
        IPage<UserBean> page = userDao.queryUnallocatedList(new Page<>(req.getPageNo(), req.getPageSize()), req.getRoleId(), req.getMobile(), req.getUserName());

        List<UserRespVo> list = page.getRecords()
                .stream()
                .map(x -> {
                    UserRespVo resp = new UserRespVo();
                    resp.setId(x.getId());//主键
                    resp.setMobile(x.getMobile());//手机号码
                    resp.setUserName(x.getUserName());//用户账号
                    resp.setNickName(x.getNickName());//用户昵称
                    resp.setUserType(x.getUserType());//用户类型（00系统用户）
                    resp.setAvatar(x.getAvatar());//头像路径
                    resp.setEmail(x.getEmail());//用户邮箱
                    resp.setPassword(x.getPassword());//密码
                    resp.setStatus(x.getStatus());//状态(1:正常，0:禁用)
                    resp.setDeptId(x.getDeptId());//部门ID
                    resp.setLoginIp(x.getLoginIp());//最后登录IP
                    resp.setLoginDate(x.getLoginDate());//最后登录时间
                    resp.setLoginBrowser(x.getLoginBrowser());//浏览器类型
                    resp.setLoginOs(x.getLoginOs());//操作系统
                    resp.setPwdUpdateDate(x.getPwdUpdateDate());//密码最后更新时间
                    resp.setRemark(x.getRemark());//备注
                    resp.setDelFlag(x.getDelFlag());//删除标志（0代表删除 1代表存在）
                    resp.setCreateTime(x.getCreateTime());//创建时间
                    resp.setUpdateTime(x.getUpdateTime());//修改时间
                    return resp;
                })
                .collect(Collectors.toList());

        return Result.success(new ResultPage<>(list, page.getCurrent(), page.getSize(), page.getTotal()));
    }

    /**
     * 取消授权用户
     *
     * @param authUserReq 请求参数
     * @return Integer
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<Integer> cancelAuthUser(CancelAuthUserReq authUserReq) {
        Long roleId = authUserReq.getRoleId();////用户id
        Long userId = authUserReq.getUserId();//角色id

        if (roleId.equals(1L)) {
            return Result.error("不允许操作超级管理员角色");
        }

        int i = userRoleDao.delete(Wrappers.<UserRoleBean>lambdaUpdate()
                                           .eq(UserRoleBean::getUserId, userId)
                                           .eq(UserRoleBean::getRoleId, roleId));
        return Result.success(i);
    }

    /**
     * 批量取消授权用户
     *
     * @param userAllReq 请求参数
     * @return Integer
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<Integer> batchCancelAuthUser(CancelAuthUserAllReq userAllReq) {
        List<Long> userIds = userAllReq.getUserIds();//用户ids
        Long roleId = userAllReq.getRoleId();//角色id

        if (roleId.equals(1L)) {
            return Result.error("不允许操作超级管理员角色");
        }

        int i = userRoleDao.delete(Wrappers.<UserRoleBean>lambdaUpdate()
                                           .in(UserRoleBean::getUserId, userIds)
                                           .eq(UserRoleBean::getRoleId, roleId));
        return Result.success(i);
    }

    /**
     * 批量选择用户授权
     *
     * @param userAllReq 请求参数
     * @return Integer
     * @author 刘飞华
     * @date: 2025/01/15 15:09:35
     */
    @Override
    public Result<Integer> batchAuthUser(SelectAuthUserAllReq userAllReq) {
        List<Long> userIds = userAllReq.getUserIds();//用户ids
        Long roleId = userAllReq.getRoleId();//角色id

        userIds.forEach(userId -> userRoleDao.insert(new UserRoleBean(userId, roleId)));

        return Result.success();
    }
}